home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Packmags
/
Source, The - Issue 5 (1993)(Epsilon)[WB].zip
/
Source, The - Issue 5 (1993)(Epsilon)[WB].adf
/
Source
/
Vectors
/
Rendering
/
Ellipse.lha
/
circles.code
next >
Wrap
Internet Message Format
|
1989-10-24
|
5KB
From albanycs!leah:rsb584 Sat Jan 9 02:42:36 1988
Received: by albanycs.albany.edu (5.54/4.8)
id AA08556; Sat, 9 Jan 88 01:49:15 EST
Date: Sat, 9 Jan 88 01:49:12 EST
From: albanycs!leah:rsb584 ( Raymond S Brand)
Received: by leah.Albany.EDU (5.58/1.1)
id AA04516; Sat, 9 Jan 88 01:49:12 EST
Message-Id: <8801090649.AA04516@leah.Albany.EDU>
To: albanycs:beowulf!rsbx
>From mcdonald@uxe.cso.uiuc.edu Wed Jan 6 12:31:00 1988
Path: leah!uwmcsd1!bbn!oberon!bloom-beacon!gatech!purdue!i.cc.purdue.edu!j.cc.purdue.edu!pur-ee!uiucdcs!uxc.cso.uiuc.edu!uxe.cso.uiuc.edu!mcdonald
From: mcdonald@uxe.cso.uiuc.edu
Newsgroups: comp.graphics
Subject: Re: circles with non-unity aspect ratio
Message-ID: <46900007@uxe.cso.uiuc.edu>
Date: 6 Jan 88 17:31:00 GMT
References: <807@hsi.UUCP>
Lines: 120
Nf-ID: #R:hsi.UUCP:807:uxe.cso.uiuc.edu:46900007:000:3894
Nf-From: uxe.cso.uiuc.edu!mcdonald Jan 6 11:31:00 1988
>I am trying to draw "good" circles on an AT&T 3b1 (aka, UNIX PC).
>The problem is the aspect ratio - it is nowhere near unity.
>I have gone through McIlroy's paper ("Best Approximate Circles on
>Integer Grids") and Foley & Van Dam. I see two ways to draw the circle:
>(1) Utilize "user coordinates" (in this case a 4096 by 4096 square)
Bad idea.
>(2) Utilize "device coordinates" (430 by 288, in this case).
The correct way.
>Am I missing something simple that would make it easy to draw my
>circles ?? Can anyone point me to another reference that adequately
>covers the drawing of a circle on a screen with a non-unity aspect
>ratio (F & VD mention a few, but before I go digging up the articles,
>does anyone know if these are what I should be looking at) ??
It's not really easy to generate good looking circles on a pixel grid.
After trying lots of different things, I have adopted the following
ellipse drawer. It draws ellipses in pixel space; to get circles you
feed it the proper height and width in pixels. This thine works really
well for circles with a radius greater than 4. For smaller circles,
it pays in terms of looking nice to draw each size as a special case.
The enclosed program uses the standard Bresnahan algorithm for the
best approximation of a curve. It is optimized for speed.
There was a good reference to this an article in Dr. Dobbs Journal in 1987,
but for circles only, not ellipses.
I hope that this can help you.
Doug McDonald
Department of Chemistry
University of Illinois
/* Draw an ellipse with width irx and height iry */
/* from a routine by Tim Hogan in Dr. Dobb's Journal May '85 p.40 */
/* Improved by calculating increments incrementally, thus removing all */
/* multiplies from the loops. These multiplies were very bad since they */
/* were (long)*(long). */
/* Written Sept. 7, 1987 by J.D. McDonald (public domain) */
static long alpha, beta, alpha2, alpha4, beta2, beta4, d;
static long ddx, ddy, alphadx, betady;
static int dy, dx;
extern void e_start(int, int, int ,int);
extern void e_xd();
extern void e_xdyu();
extern void e_yu();
ellipse(x, y, irx, iry, c)
int x, y, irx, iry;
unsigned c;
{
beta = (long) irx *(long) irx;
alpha = (long) iry *(long) iry;
if (alpha == 0L)
alpha = 1L;
if (beta == 0L)
beta = 1L;
dy = 0;
dx = irx;
alpha2 = alpha << 1;
alpha4 = alpha2 << 1;
beta2 = beta << 1;
beta4 = beta2 << 1;
alphadx = alpha * dx;
betady = 0;
ddx = alpha4 * (1 - dx);
ddy = beta2 * 3;
d = alpha2 * ((long) (dx - 1) * dx) + alpha + beta2 * (1 - alpha);
e_start(x - dx, x + dx, y, c);
/* e_start draws left and rightmost pixels on vertical centerline */
/* e_yu draws a pixel in right top quadrant one up from previous */
/* e_xd draws a pixel in right top quadrant one left from previous*/
/* e_xdyu draws a pixel in right top quadrant up and left from */
/* previous. e_yu, e_xd, and e_xdyu also draw the corresponding */
/* pixels in the other three quadrants. */
/* c is the color */
do {
if (d >= 0) {
d += ddx;
dx--;
alphadx -= alpha;
ddx += alpha4;
e_xdyu();
} else
e_yu();
d += ddy;
dy++;
betady += beta;
ddy += beta4;
} while (alphadx > betady);
d = beta2 * ((long) dy * (dy + 1)) + alpha2 * ((long) dx * (dx - 2) + 1)
+ beta * (1 - alpha2);
ddx = alpha2 * (3 - (dx << 1));
ddy = beta4 * (1 + dy);
do {
if (d <= 0) {
d += ddy;
ddy += beta4;
dy++;
e_xdyu();
} else
e_xd();
d += ddx;
ddx += alpha4;
dx--;
} while (dx > 0);
}